import Watcher from "./observe/watcher";
import { createElementVNode, createTextVNode } from "./vdom"

function createElm(vnode) {
    let { tag, data, children, text } = vnode
    if (typeof tag === 'string') {//标签
        vnode.el = document.createElement(tag)
        patchProps(vnode.el, data)
        children.forEach(child => {
            vnode.el.appendChild(createElm(child))
        });
    } else {// 文本
        vnode.el = document.createTextNode(text)
    }
    return vnode.el
}

function patchProps(el, props) {
    for (const key in props) {
        if (key === 'style') {
            for (const styleName in props.style) {
                el.style[styleName] = props.style[styleName]
            }

        } else {
            el.setAttribute(key, props[key])
        }
    }

}

function patch(oldVNode, vnode) {
    const isRealElement = oldVNode.nodeType
    if (isRealElement) {
        const elm = oldVNode // 获取真实元素
        const parentElm = elm.parentNode// 拿到父元素
        let newElm = createElm(vnode)
        parentElm.insertBefore(newElm, elm.nextSibling)
        parentElm.removeChild(elm)
        return newElm
        //    console.log(newElm);


    } else {
        //diff算法
    }
}

export function initLifeCycle(Vue) {
    Vue.prototype._update = function (vnode) {

        const vm = this
        const el = vm.$el
        // patch 初始化和更新
        vm.$el = patch(el, vnode)
    }
    // _c('div',{},...children)
    Vue.prototype._c = function () {
        return createElementVNode(this, ...arguments)
    }
    // _v(text)
    Vue.prototype._v = function () {
        return createTextVNode(this, ...arguments)

    }
    Vue.prototype._s = function (value) {
        if (typeof value !== 'object') return value
        return JSON.stringify(value)
    }
    Vue.prototype._render = function () {
        return this.$options.render.call(this)
    }
}

// 入口
export function mountComponent(vm, el) {
    vm.$el = el
    // 1. 调用render方法产生虚拟dom
    const updateComponent = () => {
        vm._update(vm._render())
    }
    // debugger
    const watcher = new Watcher(vm, updateComponent, true)//true用于标识是一个渲染watcher
    // console.log(watcher)
    // 2. 虚拟dom转真实dom
    // 3. 插入到el元素中
}

export function callHook(vm,hook) {//调用钩子函数
   
    const handlers=vm.$options[hook]
    // console.log(handlers,'handlers')
    if(handlers){
        handlers.forEach(handler=>handler.call(vm))
    }
}